# -*- coding: utf-8 -*-
# pylint: disable-msg=E1101
"""
@author: Sergiy Tsymbalyuk
"""

import os, math

from pylons import config

from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib.styles import ParagraphStyle, TA_CENTER
from reportlab.platypus.paragraph import Paragraph
from reportlab.platypus.tables import Table, GRID_STYLE
from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame, Flowable

from chowa import chowa_path

from hrms.lib.base import Session
from hrms.model.person import Employee
from hrms.model.worktime import *


class TimesheetTemplate(BaseDocTemplate):
    def __init__(self, filename, **kwargs):
        BaseDocTemplate.__init__(self, filename, **kwargs)
        template = PageTemplate('normal', Frame(18, 18, 800, 552))
        self.addPageTemplates(template)


class t(Flowable):
    _is_vertical = False
    
    def __init__(self, text):
        Flowable.__init__(self)
        self.utext = text
    
    def draw(self):
        tokens = self.utext.split('\n')
        self.canv.saveState()
        if self._is_vertical: self.canv.rotate(90)
        pos = len(tokens) * 4 - 5
        for token in tokens:
            self.canv.drawCentredString(0, pos, token)
            pos -= 8
        self.canv.restoreState()

class vt(t):
    _is_vertical = True


HEADER = [
    [vt(u'№ п/п'), vt(u'Табельний номер'), vt(u'Стать (ж/ч)'), u'П.І.Б., посада',
     u'Відмітки про явки та неявки за числами місяця (годин)'] + [''] * 15 +
    [u'Відпрацьовано за місяць'] + [''] * 5 +
    [vt(u'Всього неявок'),
     u'з причин за місяць'] + [''] * 12 +
    [vt(u'Оклад, тарифна ставка, грн.')],
    
    [''] * 4 +
    ['%02d' % d for d in range(1, 16)] + ['X'] +
    [vt('днів'), 'годин'] + [''] * 4 +
    ['',
     vt(u'основна та додаткова відпустки'),
     vt(u'відпустки у зв’язку з навчанням,\nтворчі, в обов. порядку та інші'),
     vt(u'відпустки без збереження\nзаробітноїплати за згодою сторін'),
     vt(u'відпуст-ки без збереження з/п на\nперіод припинення виконання робіт'),
     vt(u'перевод на неповний робочий день\n(тиждень)'),
     vt(u'тимчасовий перевод\nна інше підприємство'),
     vt(u'простої'),
     vt(u'прогули'),
     vt(u'страйки'),
     vt(u'тимчасова непрацездатність'),
     vt(u'інші'),
     vt(u'відрядження'),
     vt(u'відпустка у зв’язкуз вагітністю\nі пологами'), ''],
    
    [''] * 21 + [vt(u'всього'), u'з них:'] + [''] * 18,
    
    [''] * 4 +
    ['%02d' % d for d in range(16, 32)] +
    ['', '', vt(u'надурочно'), vt(u'нічних'), vt(u'вечірніх'), vt(u'вихідних,\nсвяткових'),
     u'години',
     u'коди\n8–10',
     u'коди\n11–15,\n17, 22',
     u'коди\n18',
     u'коди\n19',
     u'коди\n20',
     u'коди\n21',
     u'коди\n23',
     u'коди\n24',
     u'коди\n25',
     u'коди\n26–27',
     u'коди\n28–30',
     u'коди\n7',
     u'коди\n16', ''],
    
    [''] * 26 + ['дні/год.'] * 14 + [''],
    range(1, 42)
]

TIMESHEET_STYLE = [('FONT', (0, 0), (-1, -1), 'Serif'), 
                   ('SIZE', (0, 0), (-1, -1), 7),
                   ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                   ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                   ('TOPPADDING', (0, 0), (-1, -1), 4),
                   ('BOTTOMPADDING', (0, 0), (-1, -1), 2),]

WIDTHS = [12, 36, 12, 78] + [12] * 16 + [24, 24] + [16] * 4 + [24] * 14 + [36]
        

def generate_pdf(timesheet_id):
    sans_font = os.path.join(chowa_path, 'fonts', 'LiberationSans-Regular.ttf')
    serif_font = os.path.join(chowa_path, 'fonts', 'LiberationSerif-Regular.ttf')
    pdfmetrics.registerFont(TTFont('Sans', sans_font))
    pdfmetrics.registerFont(TTFont('Serif', serif_font))
    
    timesheet = Session.query(Timesheet).get(timesheet_id)
    
    query = Session.query(WorkingMonth).join(Employee)
    query = query.filter(WorkingMonth.timesheet_id == timesheet_id)
    query = query.order_by(Employee.surname,
                           Employee.name,
                           Employee.patronymic)
    employees = query.all()
    
    filename = 'timesheet_%d.%02d_%d.pdf' % (timesheet.year, timesheet.month, timesheet.office_id)
    file_path = os.path.join(config.get('temp_dir'), filename)
    doc = TimesheetTemplate(file_path, pagesize=landscape(A4))
    story = []
    
    estyle = ParagraphStyle('estyle')
    estyle.fontName = 'Serif'
    estyle.fontSize = 7
    estyle.alignment = TA_CENTER
    estyle.leading = 10
    
    
#    codes = Session.query(WorkingDayCode).all()
#    data = [[Paragraph(code.description, estyle), code.abbreviation, code.number] for code in codes]
#    table = Table(data[:16], colWidths=[312, 48, 48], rowHeights=[15, 30, 15, 15, 15, 15, 15, 15, 15, 30, 15, 15, 30, 30, 30, 35])
#    table.setStyle(GRID_STYLE)
#    table.setStyle(TIMESHEET_STYLE)
#    table.
#    table.drawOn(sheet, 12, 36)
#    
#    table = Table(data[16:30] + [''], colWidths=[312, 48, 48], rowHeights=[30, 30, 15, 30, 30, 30, 15, 15, 15, 15, 30, 15, 15, 15, 35])
#    table.setStyle(GRID_STYLE)
#    table.setStyle(TIMESHEET_STYLE)
#    table.wrapOn(sheet, 300, 44)
#    table.drawOn(sheet, 420, 36)
#    sheet.showPage()
    
    data = list(HEADER)
    for employee in employees:
        index = employees.index(employee)
        if (index - 7) % 12 == 0:
            data += [range(1, 42)]
        
        e = employee.employee
        position = unicode(e.position).lower()
        tokens = [unicode(e.name), unicode(e.patronymic) + ','] + position.split(' ')
        full_name = unicode(e.surname)
        for token in tokens:
            test_name = '%s %s' % (full_name, token)
            rows = test_name.split('\n')
            sep = '\n'
            if len(rows[-1]) < 22 or token == '-':
                sep = ' '
            full_name += sep + token
        gender = u'ж' if e.gender == 'F' else u'ч'
        
        total = [range(7, 31),
                 [8, 9, 10], [11, 12, 13, 14, 15, 17, 22],
                 [18], [19], [20], [21], [23], [24], [25],
                 [26, 27], [28, 29, 30], [7], [16]]
        days_data = []
        hours_data = []
        for codes in total:
            total_days = [day.hours for day in employee.days if day.code_id in codes]
            days_data += [len(total_days)]
            hours_data += [sum(total_days)]
        
        overtime_hours = []
        for code in [5, 4, 3, 6]:
            hours = [day.hours or 0 for day in employee.days if day.code_id == code]
            overtime_hours += [sum(hours)]
        working_hours = [day.hours or 0 for day in employee.days if day.code_id == 1]
        
        not_enough_days = [''] * (31 - len(employee.days))
        data += [[index + 1, employee.number, gender, t(full_name)] + 
                 [unicode(day.code or '') for day in employee.days[:15]] + ['X'] +
                 [len(working_hours), sum(working_hours)] + overtime_hours +
                 days_data + [int(employee.salary or 0)]]
        data += [[''] * 4 + [unicode(day.hours or '') for day in employee.days[:15]] + ['X'] + [''] * 20]
        data += [[''] * 4 + [unicode(day.code or '') for day in employee.days[15:31]] + not_enough_days + [''] * 6 + hours_data + ['']]
        data += [[''] * 4 + [unicode(day.hours or '') for day in employee.days[15:31]] + not_enough_days + [''] * 20]
    
    data_rows = 4 * len(employees) + (len(employees) + 4) / 12
    table = Table(data, colWidths=WIDTHS, rowHeights=([12, 12, 100, 48, 12, 11] + [11] * data_rows))
    table.setStyle(GRID_STYLE)
    table.setStyle(TIMESHEET_STYLE)
    # Header
    table.setStyle([('SPAN', (0, 0), (0, 4)),
                    ('SPAN', (1, 0), (1, 4)),
                    ('SPAN', (2, 0), (2, 4)),
                    ('SPAN', (3, 0), (3, 4)),
                    ('SPAN', (4, 0), (19, 0)),
                    ('SPAN', (20, 0), (25, 0)),
                    ('SPAN', (20, 1), (20, 4)),
                    ('SPAN', (21, 1), (25, 1)),
                    ('SPAN', (21, 2), (21, 4)),
                    ('SPAN', (22, 2), (25, 2)),
                    ('SPAN', (26, 0), (26, 2)),
                    ('SPAN', (27, 0), (39, 0)),
                    ('SPAN', (40, 0), (40, 4))] + 
                   [('SPAN', (i, 1), (i, 2)) for i in range(4, 20)] +
                   [('SPAN', (i, 3), (i, 4)) for i in range(4, 20)] +
                   [('SPAN', (i, 3), (i, 4)) for i in range(22, 26)] +
                   [('SPAN', (i, 1), (i, 2)) for i in range(27, 40)])
    # Data
    for r in range(0, len(employees)):
        first_row = 4 * r + 6 + (r + 5) / 12
        table.setStyle([('SPAN', (i, first_row), (i, first_row + 3)) for i in range(4) + range(20, 26)])
        table.setStyle([('SPAN', (i, first_row + j), (i, first_row + j + 1))
                        for i in range(26, 41)
                        for j in [0, 2]])
    heading_style = ParagraphStyle('heading')
    heading_style.alignment = TA_CENTER
    heading_style.fontName = 'Serif'
    heading_style.fontSize = 14
    heading_style.spaceAfter = 18
    story.append(Paragraph(u'ТАБЕЛЬ ОБЛІКУ РОБОЧОГО ЧАСУ', heading_style))
    story.append(table)
    doc.multiBuild(story)
    
    return file_path
